/**
 * Copyright 2012 Roger Cockshutt
 * krakenbrau@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.parallelrl.display;

import java.util.Arrays;
import java.util.List;
import java.util.Vector;

import com.googlecode.blacken.terminal.BlackenKeys;
import com.googlecode.parallelrl.Config;
import com.googlecode.parallelrl.data.KeyCode;
import com.googlecode.parallelrl.util.Message;

/**
 * @author Roger Cockshutt
 *
 */
public class Menu {
	
	private static char[] keys = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
		't','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q',
		'R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9'};
	
	private Vector<Message> options = new Vector<>();
	private Vector<Message> descriptions = new Vector<>();
	private final Message menuTitle;
	private int selection;
	
	public Menu(Message title) {
		menuTitle = title;
		selection = 0;
	}
	
	public Menu(String title, int color) {
		this(new Message(title, color));
	}
	
	public Menu(String title) {
		this(title, Colors.SVG.White.value);
	}
	
	public void addOption(String text, Integer color) {
		addOptions(new Message(text, color));
	}
	
	public void addOption(String text, Integer color, String description, Integer dcolor) {
		addOption(text, color);
		descriptions.set(options.size() - 1, new Message(description, dcolor));
	}
	
	public void addOptions(Message... messages) {
		for (Message item : messages) {
			options.add(item);
			descriptions.setSize(options.size());
		}
	}
	
	public void removeOptions(Integer... indices) {
		for (Integer index : indices) {
			options.remove(index);
		}
	}
	
	@SuppressWarnings("unused")
	public String show() {
		int startx = Config.windowSize.x / 8;
		int starty = Config.windowSize.y / 5;
		int endx = Config.windowSize.x * 6 / 8;
		int endy = Config.windowSize.y * 4 / 5;
		int descx = startx * 4;
		int descendx = Config.windowSize.x - 2;
		int desclinelength = descendx - descx;
		
		Vector<Character> validOptions = new Vector<>();
		for (int j = 0; j < options.size(); j++) {
			validOptions.add(keys[j]);
		}
		
		int ch = BlackenKeys.NO_KEY;
		int bgClr;
		while (!validOptions.contains((char) ch)) {
			if (ch == KeyCode.Esc.codePoint) {
				return null;
			}
			Screen.get().clear();
			Screen.get().puts(menuTitle.getMessage(), 1, 1, menuTitle.getColor(), Screen.get().getDefaultBg());
			if (ch == KeyCode.Up.codePoint) {
				selection = (selection + options.size() - 1) % options.size();
			}
			if (ch == KeyCode.Down.codePoint) {
				selection = (selection + 1) % options.size();
			}
			if (ch == KeyCode.Return.codePoint
					|| ch == KeyCode.NumEnter.codePoint) {
				return options.get(selection).getMessage();
			}
			int i = 0;
			for (Message option : options) {
				bgClr = Screen.get().getDefaultBg();
				if (i + starty > endy) {
					break;
				}
				String entry = keys[i] + " -  " + option.getMessage();
				
				if (i == selection) {
					bgClr = Colors.libTCOD.grey.dark;
				}
				Screen.get().puts(entry, i + starty, startx, option.getColor(), bgClr);
				i++;
			}
			if (descriptions.get(selection) != null) {
				Message description = descriptions.get(selection);
				String dText = description.getMessage();
				List<String> splitdText = Arrays.asList(dText.split("\\n"));
				List<String> lines = new Vector<>();
				for (String line : splitdText) {
					while (line.length() > desclinelength) {
						lines.add(line.substring(0, desclinelength));
						line = line.substring(desclinelength);
					}
					lines.add(line);
				}
				
				for (int y = 0; y < lines.size() && y < endy - starty; y++) {
					Screen.get().puts(lines.get(y), starty + y, descx, description.getColor(), Screen.get().getDefaultBg());
				}
			}
			Screen.get().refresh();
			ch = Screen.get().getch();
		}
		
		return options.get(validOptions.indexOf((char) ch)).getMessage();
	}
	

}
